package cn.xwj.Nettytest.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

/**
 * Created by thinkjoy on 2017/6/16.
 */
public class Server {
    public static void main(String[] args){
        //1.第一个线程组是用于接收Client端连接的(用于管理连接到server端的client的连接数的线程池)
        EventLoopGroup bossGroup =new NioEventLoopGroup();
        //2.第二个线程组是用于实际的业务处理的(管理实际操作的线程池)
        EventLoopGroup workerGroup=new NioEventLoopGroup();
        ServerBootstrap b=new ServerBootstrap();
        //绑定两个线程池
        b.group(bossGroup,workerGroup);
        //指定NIO的模式，如果是客户端就是NioSocketChannel
        b.channel(NioServerSocketChannel.class);
        b.option(ChannelOption.SO_BACKLOG,1024);//TCP的缓冲区设置
        b.option(ChannelOption.SO_SNDBUF, 32*1024);//设置发送缓冲的大小
        b.option(ChannelOption.SO_RCVBUF, 32*1024);//设置接收缓冲区大小
        b.option(ChannelOption.SO_KEEPALIVE, true);//保持连续
        b.childHandler(new ChannelInitializer<SocketChannel>() {
            protected void initChannel(SocketChannel socketChannel) throws Exception {
                //拆包粘包定义结束字符串（第一种解决方案）
//                ByteBuf buf= Unpooled.copiedBuffer("$_".getBytes());
                //在管道中加入结束字符串
//                socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf));

                // 以("\n")为结尾分割的 解码器
                socketChannel.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                //定义接收类型为字符串把ByteBuf转成String
                socketChannel.pipeline().addLast("decoder",new StringDecoder());
                socketChannel.pipeline().addLast("encoder", new StringEncoder());
                //在这里配置具体数据接收方法的处理
                socketChannel.pipeline().addLast("handler",new ServerHandler());
            }
        });
        try {
//            绑定端口
            ChannelFuture future=b.bind(9527).sync();
            //等待关闭(程序阻塞在这里等待客户端请求)
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            //关闭线程
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
